import { Language, LanguageNode, Languages, LanguageType } from '@/interface';
import { isEmpty } from '@/utils/validate';

export class Node implements LanguageNode {
  children: LanguageNode[] = [];
  key: string = '';
  languages: Partial<LanguageType> = {};
  parent: LanguageNode | null = null;

  get fullPath() {
    return this.parent ? `${this.parent.fullPath}.${this.key}` : this.key;
  }

  constructor(
    key: string,
    value: { [k: string]: any },
    json: Partial<Languages>,
  ) {
    this.key = key;
    this.children = [];
    this.languages = {};
    if (typeof value === 'object') {
      Object.keys(value).forEach((k) => {
        this.append(new Node(k, value[k], json));
      });
    }

    if (isEmpty(json)) return;
    setTimeout(() => {
      this.languages = Object.keys(json).reduce((p: any, c) => {
        const messages = json[c];
        // 获取到当前路径的值
        p[c] = this.getProperty(messages, this.fullPath);
        return p;
      }, {} as { [key: string]: any });
    }, 0);
  }

  public append(child: LanguageNode) {
    child.parent = this;
    this.children.push(child);
  }

  public remove() {
    if (!this.parent) return;
    this.parent.children = this.parent.children.filter(
      (child) => child.key !== this.key,
    );

    if (this.parent.children.length === 0) {
      this.parent.languages = {};
    }
  }

  public setContent(lang: Language, content: Languages) {
    this.languages = {
      ...this.languages,
      [lang]: content,
    };
  }

  private getProperty(obj: any, path: string) {
    let paths = path.split('.');
    let value = obj;
    const key = paths.shift();
    if (!key) return value;
    do {
      if (value[key]) {
        value = value[key];
      } else {
        return value;
      }
    } while (paths.length);

    return value;
  }
}
